using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using Svg;
using Svg.Transforms;

namespace SvgToFontConverter.Services
{
    /// <summary>
    /// 专业SVG处理服务，使用SVG.NET库进行精确的SVG解析和坐标转换
    /// </summary>
    public class SvgProcessorService
    {
        private const double FontAscent = 800;  // 字体上升部
        private const double FontDescent = 200; // 字体下降部
        private const double FontEmSize = FontAscent + FontDescent; // EM方框大小
        
        /// <summary>
        /// 处理SVG文件并转换为字体路径数据
        /// </summary>
        /// <param name="svgFilePath">SVG文件路径</param>
        /// <returns>转换后的路径数据</returns>
        public string ProcessSvgFile(string svgFilePath)
        {
            try
            {
                if (!File.Exists(svgFilePath))
                {
                    Debug.WriteLine($"SVG文件不存在: {svgFilePath}");
                    return CreateDefaultPath();
                }

                // 读取SVG文件内容
                var svgContent = File.ReadAllText(svgFilePath);
                Debug.WriteLine($"成功读取SVG文件: {svgFilePath}");
                Debug.WriteLine($"SVG内容长度: {svgContent.Length}");

                // 使用简单的正则表达式提取路径数据
                var pathData = ExtractPathFromSvgContent(svgContent);
                
                if (string.IsNullOrEmpty(pathData))
                {
                    Debug.WriteLine("未能提取到有效的路径数据");
                    return CreateDefaultPath();
                }

                Debug.WriteLine($"提取的原始路径: {pathData}");
                
                // 转换坐标系统
                var fontPath = ConvertToFontCoordinatesSimple(pathData, svgContent);
                Debug.WriteLine($"转换后的字体路径: {fontPath}");
                
                return fontPath;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"处理SVG文件失败: {ex.Message}");
                Debug.WriteLine($"堆栈跟踪: {ex.StackTrace}");
                return CreateDefaultPath();
            }
        }

        /// <summary>
        /// 从SVG内容中提取路径数据
        /// </summary>
        /// <param name="svgContent">SVG内容</param>
        /// <returns>路径数据字符串</returns>
        private string ExtractPathFromSvgContent(string svgContent)
        {
            try
            {
                var pathBuilder = new StringBuilder();
                
                // 首先处理带有transform的g元素
                var gPattern = @"<g[^>]*transform\s*=\s*[""']([^""']*)[""'][^>]*>([\s\S]*?)</g>";
                var gMatches = System.Text.RegularExpressions.Regex.Matches(svgContent, gPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                
                foreach (System.Text.RegularExpressions.Match gMatch in gMatches)
                {
                    var transformAttr = gMatch.Groups[1].Value;
                    var gContent = gMatch.Groups[2].Value;
                    
                    // 解析transform属性
                    double translateX = 0, translateY = 0, scaleX = 1, scaleY = 1;
                    
                    var translateMatch = System.Text.RegularExpressions.Regex.Match(transformAttr, @"translate\s*\(\s*([^,\s]+)\s*,?\s*([^\)\s]*)\s*\)", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                    if (translateMatch.Success)
                    {
                        double.TryParse(translateMatch.Groups[1].Value, out translateX);
                        if (translateMatch.Groups[2].Success && !string.IsNullOrEmpty(translateMatch.Groups[2].Value))
                        {
                            double.TryParse(translateMatch.Groups[2].Value, out translateY);
                        }
                    }
                    
                    var scaleMatch = System.Text.RegularExpressions.Regex.Match(transformAttr, @"scale\s*\(\s*([^,\s]+)\s*,?\s*([^\)\s]*)\s*\)", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                    if (scaleMatch.Success)
                    {
                        double.TryParse(scaleMatch.Groups[1].Value, out scaleX);
                        if (scaleMatch.Groups[2].Success && !string.IsNullOrEmpty(scaleMatch.Groups[2].Value))
                        {
                            double.TryParse(scaleMatch.Groups[2].Value, out scaleY);
                        }
                        else
                        {
                            scaleY = scaleX;
                        }
                    }
                    
                    Debug.WriteLine($"G元素transform - translate: x={translateX}, y={translateY}, scale: x={scaleX}, y={scaleY}");
                    
                    // 在g元素内容中查找path元素
                    var pathPattern = @"<path[^>]*d\s*=\s*[""']([^""']*)[""'][^>]*>";
                    var pathMatches = System.Text.RegularExpressions.Regex.Matches(gContent, pathPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                    
                    foreach (System.Text.RegularExpressions.Match pathMatch in pathMatches)
                    {
                        if (pathMatch.Groups.Count > 1)
                        {
                            var pathData = pathMatch.Groups[1].Value.Trim();
                            if (!string.IsNullOrEmpty(pathData))
                            {
                                // 应用transform变换到路径数据
                                var transformedPath = ApplyTransformToPath(pathData, translateX, translateY, scaleX, scaleY);
                                pathBuilder.Append(transformedPath).Append(" ");
                            }
                        }
                    }
                }
                
                // 然后处理没有transform的直接path元素
                var directPathPattern = @"<path[^>]*d\s*=\s*[""']([^""']*)[""'][^>]*>";
                var directMatches = System.Text.RegularExpressions.Regex.Matches(svgContent, directPathPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                
                foreach (System.Text.RegularExpressions.Match match in directMatches)
                {
                    // 检查这个path是否已经在g元素中处理过了
                    var pathElement = match.Value;
                    bool isInGroup = false;
                    
                    foreach (System.Text.RegularExpressions.Match gMatch in gMatches)
                    {
                        if (gMatch.Groups[2].Value.Contains(pathElement))
                        {
                            isInGroup = true;
                            break;
                        }
                    }
                    
                    if (!isInGroup && match.Groups.Count > 1)
                    {
                        var pathData = match.Groups[1].Value.Trim();
                        if (!string.IsNullOrEmpty(pathData))
                        {
                            pathBuilder.Append(pathData).Append(" ");
                        }
                    }
                }
                
                var result = pathBuilder.ToString().Trim();
                return string.IsNullOrEmpty(result) ? CreateDefaultPath() : result;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"提取路径失败: {ex.Message}");
                return CreateDefaultPath();
            }
        }



        /// <summary>
        /// 将SVG坐标转换为字体坐标系统（简化版本）
        /// </summary>
        /// <param name="pathData">原始路径数据</param>
        /// <param name="svgContent">SVG内容</param>
        /// <returns>转换后的路径数据</returns>
        private string ConvertToFontCoordinatesSimple(string pathData, string svgContent)
        {
            try
            {
                // 解析viewBox
                var viewBoxMatch = System.Text.RegularExpressions.Regex.Match(svgContent, @"viewBox\s*=\s*[""']([^""']*)[""']", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                double svgX = 0, svgY = 0, svgWidth = 100, svgHeight = 100;
                
                if (viewBoxMatch.Success)
                {
                    var viewBoxValues = viewBoxMatch.Groups[1].Value.Split(new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
                    if (viewBoxValues.Length >= 4)
                    {
                        double.TryParse(viewBoxValues[0], out svgX);
                        double.TryParse(viewBoxValues[1], out svgY);
                        double.TryParse(viewBoxValues[2], out svgWidth);
                        double.TryParse(viewBoxValues[3], out svgHeight);
                    }
                }
                
                Debug.WriteLine($"SVG坐标信息: ViewBox=({svgX}, {svgY}, {svgWidth}, {svgHeight})");
                
                // 字体标准尺寸定义
                var baselineRatio = 0.8;  // 基线位置（从顶部算起80%）
                var baseline = FontEmSize * baselineRatio;  // 基线Y坐标
                
                // 固定字符高度为750单位（从基线到大写字母稍上一点）
                var targetCharHeight = 750.0;  // 固定高度750单位
                
                // 根据固定高度计算缩放比例，保持纵横比
                var scale = targetCharHeight / svgHeight;
                
                // 移除宽度限制，让字符宽度根据高度缩放自然确定
                
                // 确保最小缩放比例，字符不能太小
                var minScale = Math.Min(targetCharHeight / svgHeight, (FontEmSize * 0.5) / Math.Max(svgWidth, svgHeight));
                if (scale < minScale)
                {
                    scale = minScale;
                }
                
                // 限制最大缩放比例
                if (scale > 20.0)
                {
                    scale = 20.0;
                }
                
                Debug.WriteLine($"字体标准: baseline={baseline:F1}, targetCharHeight={targetCharHeight:F1}");
                Debug.WriteLine($"缩放计算: 固定高度缩放scale={scale:F3}");
                
                // 计算字符实际宽度（缩放后的宽度）
                var actualCharWidth = svgWidth * scale;
                
                // 计算偏移：字符左侧对齐到左线位置
                var offsetX = 0;  // X轴：左侧对齐到左线
                var offsetY = baseline - svgHeight * scale;  // Y轴：基线减去缩放后的字符高度
                
                Debug.WriteLine($"坐标转换参数: scale={scale:F3}, offsetX={offsetX:F3}, offsetY={offsetY:F3}");
                
                // 使用正则表达式替换路径中的坐标
                var result = System.Text.RegularExpressions.Regex.Replace(pathData, 
                    @"([MLHVCSQTAZ])\s*([^MLHVCSQTAZ]*)", 
                    match => TransformPathCommand(match, svgX, svgY, svgHeight, scale, offsetX, offsetY),
                    System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                
                return result;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"坐标转换失败: {ex.Message}");
                return pathData;
            }
        }

        /// <summary>
        /// 转换路径命令中的坐标
        /// </summary>
        private string TransformPathCommand(System.Text.RegularExpressions.Match match, 
            double svgX, double svgY, double svgHeight, double scale, double offsetX, double offsetY)
        {
            try
            {
                var command = match.Groups[1].Value.ToUpper();
                var coordinates = match.Groups[2].Value.Trim();
                
                if (string.IsNullOrEmpty(coordinates))
                    return command;
                
                // 解析坐标数字
                var numbers = System.Text.RegularExpressions.Regex.Matches(coordinates, @"-?\d+(?:\.\d+)?")
                    .Cast<System.Text.RegularExpressions.Match>()
                    .Select(m => double.Parse(m.Value, CultureInfo.InvariantCulture))
                    .ToArray();
                
                if (numbers.Length == 0)
                    return match.Value;
                
                // 根据命令类型转换坐标
                var transformedNumbers = new List<double>();
                
                switch (command)
                {
                    case "M": // MoveTo
                    case "L": // LineTo
                        for (int i = 0; i < numbers.Length; i += 2)
                        {
                            if (i + 1 < numbers.Length)
                            {
                                var x = TransformX(numbers[i], svgX, scale, offsetX);
                                var y = TransformY(numbers[i + 1], svgY, svgHeight, scale, offsetY);
                                transformedNumbers.Add(x);
                                transformedNumbers.Add(y);
                            }
                        }
                        break;
                        
                    case "H": // Horizontal LineTo
                        for (int i = 0; i < numbers.Length; i++)
                        {
                            var x = TransformX(numbers[i], svgX, scale, offsetX);
                            transformedNumbers.Add(x);
                        }
                        break;
                        
                    case "V": // Vertical LineTo
                        for (int i = 0; i < numbers.Length; i++)
                        {
                            var y = TransformY(numbers[i], svgY, svgHeight, scale, offsetY);
                            transformedNumbers.Add(y);
                        }
                        break;
                        
                    case "C": // CurveTo
                        for (int i = 0; i < numbers.Length; i += 6)
                        {
                            if (i + 5 < numbers.Length)
                            {
                                // 控制点1
                                transformedNumbers.Add(TransformX(numbers[i], svgX, scale, offsetX));
                                transformedNumbers.Add(TransformY(numbers[i + 1], svgY, svgHeight, scale, offsetY));
                                // 控制点2
                                transformedNumbers.Add(TransformX(numbers[i + 2], svgX, scale, offsetX));
                                transformedNumbers.Add(TransformY(numbers[i + 3], svgY, svgHeight, scale, offsetY));
                                // 终点
                                transformedNumbers.Add(TransformX(numbers[i + 4], svgX, scale, offsetX));
                                transformedNumbers.Add(TransformY(numbers[i + 5], svgY, svgHeight, scale, offsetY));
                            }
                        }
                        break;
                        
                    case "S": // Smooth CurveTo
                    case "Q": // Quadratic CurveTo
                        for (int i = 0; i < numbers.Length; i += 4)
                        {
                            if (i + 3 < numbers.Length)
                            {
                                // 控制点
                                transformedNumbers.Add(TransformX(numbers[i], svgX, scale, offsetX));
                                transformedNumbers.Add(TransformY(numbers[i + 1], svgY, svgHeight, scale, offsetY));
                                // 终点
                                transformedNumbers.Add(TransformX(numbers[i + 2], svgX, scale, offsetX));
                                transformedNumbers.Add(TransformY(numbers[i + 3], svgY, svgHeight, scale, offsetY));
                            }
                        }
                        break;
                        
                    case "T": // Smooth Quadratic CurveTo
                        for (int i = 0; i < numbers.Length; i += 2)
                        {
                            if (i + 1 < numbers.Length)
                            {
                                var x = TransformX(numbers[i], svgX, scale, offsetX);
                                var y = TransformY(numbers[i + 1], svgY, svgHeight, scale, offsetY);
                                transformedNumbers.Add(x);
                                transformedNumbers.Add(y);
                            }
                        }
                        break;
                        
                    case "A": // Arc
                        for (int i = 0; i < numbers.Length; i += 7)
                        {
                            if (i + 6 < numbers.Length)
                            {
                                // rx, ry (半径需要缩放)
                                transformedNumbers.Add(numbers[i] * scale);
                                transformedNumbers.Add(numbers[i + 1] * scale);
                                // x-axis-rotation (角度不变)
                                transformedNumbers.Add(numbers[i + 2]);
                                // large-arc-flag, sweep-flag (标志不变)
                                transformedNumbers.Add(numbers[i + 3]);
                                transformedNumbers.Add(numbers[i + 4]);
                                // 终点坐标
                                transformedNumbers.Add(TransformX(numbers[i + 5], svgX, scale, offsetX));
                                transformedNumbers.Add(TransformY(numbers[i + 6], svgY, svgHeight, scale, offsetY));
                            }
                        }
                        break;
                        
                    case "Z": // ClosePath
                        return command;
                        
                    default:
                        return match.Value;
                }
                
                // 构建转换后的命令字符串
                var result = command + string.Join(",", transformedNumbers.Select(n => n.ToString("F2", CultureInfo.InvariantCulture)));
                return result;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"转换路径命令失败: {ex.Message}");
                return match.Value;
            }
        }

        /// <summary>
        /// 转换X坐标
        /// </summary>
        private double TransformX(double x, double svgX, double scale, double offsetX)
        {
            return offsetX + (x - svgX) * scale;
        }

        /// <summary>
        /// 转换Y坐标（优化基线对齐）
        /// </summary>
        private double TransformY(double y, double svgY, double svgHeight, double scale, double offsetY)
        {
            // 优化Y坐标转换，确保字符从基线开始
            // 将SVG坐标系转换为字体坐标系，并考虑基线对齐
            var transformedY = offsetY + (y - svgY) * scale;
            
            // 确保Y坐标在合理范围内（0到FontEmSize之间）
            return Math.Max(0, Math.Min(FontEmSize, transformedY));
        }

        /// <summary>
        /// 应用transform变换到路径数据
        /// </summary>
        private string ApplyTransformToPath(string pathData, double translateX, double translateY, double scaleX, double scaleY)
        {
            try
            {
                // 使用正则表达式匹配路径命令和坐标
                var commandPattern = @"([MmLlHhVvCcSsQqTtAaZz])([^MmLlHhVvCcSsQqTtAaZz]*)";
                var result = System.Text.RegularExpressions.Regex.Replace(pathData, commandPattern, match =>
                {
                    var command = match.Groups[1].Value;
                    var coordinates = match.Groups[2].Value.Trim();
                    
                    if (string.IsNullOrEmpty(coordinates))
                        return command;
                    
                    // 解析坐标数字
                    var numbers = System.Text.RegularExpressions.Regex.Matches(coordinates, @"-?\d+(?:\.\d+)?")
                        .Cast<System.Text.RegularExpressions.Match>()
                        .Select(m => double.Parse(m.Value, CultureInfo.InvariantCulture))
                        .ToArray();
                    
                    if (numbers.Length == 0)
                        return match.Value;
                    
                    // 应用变换到坐标
                    var transformedNumbers = new List<double>();
                    var upperCommand = command.ToUpper();
                    
                    switch (upperCommand)
                    {
                        case "M": // MoveTo
                        case "L": // LineTo
                            for (int i = 0; i < numbers.Length; i += 2)
                            {
                                if (i + 1 < numbers.Length)
                                {
                                    var x = numbers[i] * scaleX + translateX;
                                    var y = TransformYWithFlipCorrection(numbers[i + 1], scaleY, translateY);
                                    transformedNumbers.Add(x);
                                    transformedNumbers.Add(y);
                                }
                            }
                            break;
                            
                        case "H": // Horizontal LineTo
                            for (int i = 0; i < numbers.Length; i++)
                            {
                                var x = numbers[i] * scaleX + translateX;
                                transformedNumbers.Add(x);
                            }
                            break;
                            
                        case "V": // Vertical LineTo
                            for (int i = 0; i < numbers.Length; i++)
                            {
                                var y = TransformYWithFlipCorrection(numbers[i], scaleY, translateY);
                                transformedNumbers.Add(y);
                            }
                            break;
                            
                        case "C": // CurveTo
                            for (int i = 0; i < numbers.Length; i += 6)
                            {
                                if (i + 5 < numbers.Length)
                                {
                                    transformedNumbers.Add(numbers[i] * scaleX + translateX);     // x1
                                    transformedNumbers.Add(TransformYWithFlipCorrection(numbers[i + 1], scaleY, translateY)); // y1
                                    transformedNumbers.Add(numbers[i + 2] * scaleX + translateX); // x2
                                    transformedNumbers.Add(TransformYWithFlipCorrection(numbers[i + 3], scaleY, translateY)); // y2
                                    transformedNumbers.Add(numbers[i + 4] * scaleX + translateX); // x
                                    transformedNumbers.Add(TransformYWithFlipCorrection(numbers[i + 5], scaleY, translateY)); // y
                                }
                            }
                            break;
                            
                        case "Q": // QuadraticCurveTo
                            for (int i = 0; i < numbers.Length; i += 4)
                            {
                                if (i + 3 < numbers.Length)
                                {
                                    transformedNumbers.Add(numbers[i] * scaleX + translateX);     // x1
                                    transformedNumbers.Add(TransformYWithFlipCorrection(numbers[i + 1], scaleY, translateY)); // y1
                                    transformedNumbers.Add(numbers[i + 2] * scaleX + translateX); // x
                                    transformedNumbers.Add(TransformYWithFlipCorrection(numbers[i + 3], scaleY, translateY)); // y
                                }
                            }
                            break;
                            
                        case "Z": // ClosePath
                            return command;
                            
                        default:
                            // 对于其他命令，简单地应用变换
                            for (int i = 0; i < numbers.Length; i += 2)
                            {
                                if (i + 1 < numbers.Length)
                                {
                                    var x = numbers[i] * scaleX + translateX;
                                    var y = TransformYWithFlipCorrection(numbers[i + 1], scaleY, translateY);
                                    transformedNumbers.Add(x);
                                    transformedNumbers.Add(y);
                                }
                                else
                                {
                                    transformedNumbers.Add(numbers[i]);
                                }
                            }
                            break;
                    }
                    
                    // 构建转换后的命令字符串
                    return command + string.Join(",", transformedNumbers.Select(n => n.ToString("F2", CultureInfo.InvariantCulture)));
                });
                
                Debug.WriteLine($"Transform应用: 原始={pathData.Substring(0, Math.Min(50, pathData.Length))}..., 变换后={result.Substring(0, Math.Min(50, result.Length))}...");
                return result;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"应用transform失败: {ex.Message}");
                return pathData;
            }
        }
        
        /// <summary>
        /// 处理垂直翻转的Y坐标变换
        /// </summary>
        /// <param name="y">原始Y坐标</param>
        /// <param name="scaleY">Y轴缩放因子</param>
        /// <param name="translateY">Y轴平移量</param>
        /// <returns>修正后的Y坐标</returns>
        private double TransformYWithFlipCorrection(double y, double scaleY, double translateY)
        {
            if (scaleY < 0)
            {
                // 垂直翻转的特殊处理
                // 当scaleY为负数时，表示垂直翻转
                // 需要相对于翻转中心进行坐标修正
                var flipCenter = translateY; // 翻转中心通常是translate的Y值
                var transformedY = flipCenter - (y * Math.Abs(scaleY));
                
                Debug.WriteLine($"垂直翻转修正: 原始Y={y}, 翻转中心={flipCenter}, 修正后Y={transformedY}");
                return transformedY;
            }
            else
            {
                // 正常的Y坐标变换
                return y * scaleY + translateY;
            }
        }
        
        /// <summary>
        /// 创建默认路径（矩形）
        /// </summary>
        /// <returns>默认路径数据</returns>
        private string CreateDefaultPath()
        {
            return "M100 100h800v800h-800z";
        }
    }
}